package org.example.nt.gm;

import cn.gmssl.jce.provider.GMJCE;
import cn.gmssl.jsse.provider.GMJSSE;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.socket.SocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.handler.ssl.SslHandler;
import org.bouncycastle.jce.provider.BouncyCastleProvider;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
import java.io.IOException;
import java.security.*;
import java.security.cert.CertificateException;

public class NettyClientInitializer extends ChannelInitializer<SocketChannel> {
    private static final Provider GMJCE = new GMJCE();

    private static final Provider GMSSE = new GMJSSE();

    static {
        Security.insertProviderAt(GMJCE, 1);
        Security.insertProviderAt(GMSSE, 1);
    }
    @Override
    protected void initChannel(SocketChannel socketChannel) throws Exception {
        socketChannel.pipeline().addLast("tls", createSslHandler(getClientSSLContext()));
        socketChannel.pipeline().addLast("decoder", new StringDecoder());
        socketChannel.pipeline().addLast("encoder", new StringEncoder());
        socketChannel.pipeline().addLast(new NettyClientHandler());
    }

    private ChannelHandler createSslHandler(SSLContext sslContext)
    {
        SSLEngine sslEngine = sslContext.createSSLEngine();
        sslEngine.setUseClientMode(true);
        sslEngine.setNeedClientAuth(false);
        return new SslHandler(sslEngine);
    }

    private SSLContext getClientSSLContext() throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, KeyManagementException {
        try {

            KeyStore pfx = KeyStore.getInstance("PKCS12", "GMJSSE");
            String pfxfile =  "D:/ws/java/springboot-demo/netty-demo/keystore/sm2.user1.both.pfx";
            String pwdpwd = "12345678";
            pfx.load(new FileInputStream(pfxfile), pwdpwd.toCharArray());
            SSLContext sslContext = SSLContext.getInstance(GMJSSE.GMSSLv11, GMJSSE.NAME);

            sslContext.init(null, new TrustManager[]{new GMTrustManager()}, null);
            return sslContext;
        } catch (NoSuchProviderException e) {
            throw new RuntimeException(e);
        }

    }
}
